<!doctype html>



  


<html class="theme-next mist use-motion">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Java web," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />






<meta name="description" content="说明：Servlet配置使用。">
<meta name="keywords" content="Java web">
<meta property="og:type" content="article">
<meta property="og:title" content="Servlet">
<meta property="og:url" content="http://bebetter.site/2017/01/12/Software/Java Web/Servlet/index.html">
<meta property="og:site_name" content="gatewayzy">
<meta property="og:description" content="说明：Servlet配置使用。">
<meta property="og:updated_time" content="2017-01-12T05:58:56.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Servlet">
<meta name="twitter:description" content="说明：Servlet配置使用。">



<script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Mist',
    sidebar: {"position":"right","display":"always"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: 0,
      author: '博主'
    }
  };
</script>




  <link rel="canonical" href="http://bebetter.site/2017/01/12/Software/Java Web/Servlet/"/>

  <title> Servlet | gatewayzy </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-right page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">gatewayzy</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle">blog of gatewayzy</p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                Servlet
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            <span class="post-meta-item-icon">
              <i class="fa fa-calendar-o"></i>
            </span>
            <span class="post-meta-item-text">发表于</span>
            <time itemprop="dateCreated" datetime="2017-01-12T13:58:19+08:00" content="2017-01-12">
              2017-01-12
            </time>
          </span>

          
            <span class="post-category" >
              &nbsp; | &nbsp;
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="https://schema.org/Thing">
                  <a href="/categories/Softwares/" itemprop="url" rel="index">
                    <span itemprop="name">Softwares</span>
                  </a>
                </span>

                
                

              
            </span>
          

          
            
          

          

          
          

          
        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <p><strong>说明：</strong>Servlet配置使用。<br><a id="more"></a></p>
<hr>
<p>参考文章：</p>
<h2 id="Servlet简介"><a href="#Servlet简介" class="headerlink" title="Servlet简介"></a>Servlet简介</h2><hr>
<ul>
<li>Servlet是server let，服务器端小程序，相应的是applet客户端小程序，applet已经被flash等取代，运行在客户端，如浏览器中。Servlet运行在服务器端，如tomcat中，是实现了servlet规范的特殊java类。Java代码都是由web服务器调用的。</li>
<li>web.xml中的元素执行顺序为：listener监听器&gt;&gt;filter过滤器&gt;&gt;struts拦截器&gt;&gt;servlet。</li>
<li>所以是listener加载，再filter加载，再struts拦截器加载，再load-on-startup的servlet加载，web启动完成。正常关闭的时候，销毁的顺序正好是反过来的，先加载的后销毁。</li>
</ul>
<h2 id="Servlet生命周期"><a href="#Servlet生命周期" class="headerlink" title="Servlet生命周期"></a>Servlet生命周期</h2><hr>
<ul>
<li>第一次访问相应的url后，web.xml反射机制找到servlet并init加载到内存，并调用相应的service服务。init只会调用一次，也就是servlet是单例的，线程不安全。</li>
<li>第二次及以后的访问直接调用servlet的service服务。</li>
<li>当web工程reload或stop或关机都会调用destroy，清除内存中的servlet。</li>
</ul>
<h2 id="Servlet实现"><a href="#Servlet实现" class="headerlink" title="Servlet实现"></a>Servlet实现</h2><hr>
<ul>
<li>Servlet实现由3中方法：<ul>
<li>实现Servlet接口；</li>
<li>继承GenericServlet类；</li>
<li>继承HttpServlet类。</li>
</ul>
</li>
</ul>
<h3 id="实现Servlet接口"><a href="#实现Servlet接口" class="headerlink" title="实现Servlet接口"></a>实现Servlet接口</h3><p>实现javax.servlet的几个主要方法: init, getServletConfig, service, getServletInfo, destroy</p>
<ul>
<li>编写Java</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div></pre></td><td class="code"><pre><div class="line">package servlet;</div><div class="line"></div><div class="line">import java.io.IOException;</div><div class="line">import javax.servlet.Servlet;</div><div class="line">import javax.servlet.ServletConfig;</div><div class="line">import javax.servlet.ServletException;</div><div class="line">import javax.servlet.ServletRequest;</div><div class="line">import javax.servlet.ServletResponse;</div><div class="line"></div><div class="line">/**</div><div class="line"> * implements Servlet to realize a servlet</div><div class="line"> * @author dell</div><div class="line"> *</div><div class="line"> */</div><div class="line">public class MyFirstServlet implements Servlet&#123;</div><div class="line">	</div><div class="line">	/** 该函数用于初始化servlet，就是把servlet类加载到内存中，该函数之后执行一次</div><div class="line">	 * @param config</div><div class="line">	 */</div><div class="line">	public void init(ServletConfig config) throws ServletException&#123;</div><div class="line">		</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	/**获取servletConfig对象</div><div class="line">	 * @return</div><div class="line">	 */</div><div class="line">	public ServletConfig getServletConfig() &#123;</div><div class="line">		return null;</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	/**该函数是服务函数，实现业务逻辑，每次服务都会被调用</div><div class="line">	 */</div><div class="line">	public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException&#123;</div><div class="line">		System.out.println(&quot;hello...&quot;);</div><div class="line">		res.getWriter().println(&quot;hello!&quot;);</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	/**获取servlet的配置信息</div><div class="line">	 * @return</div><div class="line">	 */</div><div class="line">	public String getServletInfo() &#123;</div><div class="line">		return null;</div><div class="line">	&#125;</div><div class="line">	</div><div class="line">	/**</div><div class="line">	 * 销毁该servlet，从内存中清除，只调用一次</div><div class="line">	 */</div><div class="line">	public void destroy() &#123;</div><div class="line">		</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ul>
<li>部署servlet（Web.xml）</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</div><div class="line">&lt;web-app xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns=http://java.sun.com/xml/ns/javaee xsi:schemaLocation=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd id=&quot;WebApp_ID&quot; version=&quot;3.0&quot;&gt;</div><div class="line">	&lt;display-name&gt;tools&lt;/display-name&gt;</div><div class="line"></div><div class="line">	&lt;servlet&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyFirstServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;servlet-class&gt;servlet.MyFirstServlet&lt;/servlet-class&gt;</div><div class="line">	&lt;/servlet&gt;</div><div class="line">	&lt;servlet-mapping&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyFirstServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;url-pattern&gt;/gotoMyFirstServlet&lt;/url-pattern&gt;</div><div class="line">	&lt;/servlet-mapping&gt;</div><div class="line">&lt;/web-app&gt;</div></pre></td></tr></table></figure>
<ul>
<li>发布项目并访问：发布项目，访问<code>http://127.0.0.1:8080/javaTools/gotoMyFirstServlet</code></li>
</ul>
<h3 id="继承GenericServlet类"><a href="#继承GenericServlet类" class="headerlink" title="继承GenericServlet类"></a>继承GenericServlet类</h3><p>继承重写service方法，重写service</p>
<ul>
<li>编写java</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">package servlet;</div><div class="line">import java.io.IOException;</div><div class="line">import java.util.Date;</div><div class="line">import javax.servlet.GenericServlet;</div><div class="line">import javax.servlet.ServletException;</div><div class="line">import javax.servlet.ServletRequest;</div><div class="line">import javax.servlet.ServletResponse;</div><div class="line"></div><div class="line">public class MyGenericServlet extends GenericServlet &#123;</div><div class="line">	@Override</div><div class="line">	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException &#123;</div><div class="line">		response.getWriter().println(&quot;hello GenericServlet:&quot; + new Date());</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ul>
<li>部署servlet（web.xml）</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&lt;servlet&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyGenericServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;servlet-class&gt;servlet.MyGenericServlet&lt;/servlet-class&gt;</div><div class="line">	&lt;/servlet&gt;</div><div class="line">	&lt;servlet-mapping&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyGenericServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;url-pattern&gt;/gotoMyGenericServlet&lt;/url-pattern&gt;</div><div class="line">	&lt;/servlet-mapping&gt;</div></pre></td></tr></table></figure>
<ul>
<li>发布项目并访问：发布web项目并访问/webapp/gotoMyGenericServlet</li>
</ul>
<h3 id="继承HttpServlet"><a href="#继承HttpServlet" class="headerlink" title="继承HttpServlet"></a>继承HttpServlet</h3><ul>
<li>编写java</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">package servlet;</div><div class="line">import java.io.IOException;</div><div class="line">import javax.servlet.http.HttpServlet;</div><div class="line">import javax.servlet.http.HttpServletRequest;</div><div class="line">import javax.servlet.http.HttpServletResponse;</div><div class="line">/**</div><div class="line"> * 继承HttpServlet，发布项目，访问相应的html直接post</div><div class="line"> */</div><div class="line">public class MyHttpServlet extends HttpServlet &#123;</div><div class="line">	private static final long serialVersionUID = 8020940240259361429L;</div><div class="line"></div><div class="line">	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException &#123;</div><div class="line">		response.getWriter().println(&quot;doGet...&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException &#123;</div><div class="line">		response.getWriter().println(&quot;doPost: userName = &quot; + request.getParameter(&quot;userName&quot;));</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ul>
<li>部署servlet</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">	&lt;!-- initParam --&gt;</div><div class="line">	&lt;context-param&gt;</div><div class="line">		&lt;param-name&gt;base&lt;/param-name&gt;</div><div class="line">		&lt;param-value&gt;/javaTools&lt;/param-value&gt;</div><div class="line">	&lt;/context-param&gt;</div><div class="line">&lt;servlet&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyHttpServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;servlet-class&gt;servlet.MyHttpServlet&lt;/servlet-class&gt;</div><div class="line">	&lt;/servlet&gt;</div><div class="line">	&lt;servlet-mapping&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyHttpServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;url-pattern&gt;/gotoMyHttpServlet&lt;/url-pattern&gt;</div><div class="line">	&lt;/servlet-mapping&gt;</div></pre></td></tr></table></figure>
<ul>
<li>发布并访问：发布webapp并访问httpServlet.jsp</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">&lt;form action=&quot;$&#123;initParam.base&#125;/gotoMyHttpServlet&quot; method=&quot;post&quot;&gt;</div><div class="line">	用户名：&lt;input type=&quot;text&quot; name=&quot;userName&quot;&gt; </div><div class="line">	&lt;input type=&quot;submit&quot; value=&quot;submit&quot;&gt;</div><div class="line">&lt;/form&gt;</div></pre></td></tr></table></figure>
<ul>
<li>servlet初始化参数<ul>
<li>单个servlet的初始化参数可以在<servlet><init-param></init-param></servlet>中配置，获取的方法可以是 doGet(){String name = this. getInitParameter(“name”)}</li>
</ul>
</li>
</ul>
<h2 id="Servlet-发布细节"><a href="#Servlet-发布细节" class="headerlink" title="Servlet 发布细节"></a>Servlet 发布细节</h2><hr>
<h3 id="Servlet通配符"><a href="#Servlet通配符" class="headerlink" title="Servlet通配符"></a>Servlet通配符</h3><ul>
<li>一个servlet可以通过<servlet-mapping>映射到多个url。可以使用通配符，是非法的请求都定位到指定的入口。</servlet-mapping></li>
<li>通配符只有两种形式：<ol>
<li>使用<code>/*</code>的方式，比如<code>/asd/*</code>、<code>/123/*</code>等</li>
<li>使用<code>*.拓展名</code>的方式，比如<code>*.do</code>、<code>*.jsp</code>、<code>*.html</code>，注意拓展名并不代表真是jsp。</li>
</ol>
</li>
</ul>
<h3 id="Servlet匹配优先级"><a href="#Servlet匹配优先级" class="headerlink" title="Servlet匹配优先级"></a>Servlet匹配优先级</h3><p>规则：谁最像(匹配长度越多越优先)，就选中谁；<code>*.</code>拓展名优先级最低。</p>
<h3 id="Servlet同步"><a href="#Servlet同步" class="headerlink" title="Servlet同步"></a>Servlet同步</h3><ul>
<li>由于servlet是单例的，同样的请求使用的servlet是同一个（不同的方法），所以存在同步问题，如果servlet存在全局变量，应考虑同步问题。</li>
<li>简单的处理方法是synchronized(this) { Thread.sleep(10*1000); }</li>
</ul>
<h3 id="load-on-startup"><a href="#load-on-startup" class="headerlink" title="load-on-startup"></a>load-on-startup</h3><ul>
<li>工程发布的时候自动调用servlet，启用init方法，在init中进行定时、初始化等业务操作。</li>
<li>Load-on-startup的servlet可以和JFinal、springMVC等框架可以共同使用的，但是框架中一般都会有实现项目启动就运行的机制，不必使用servlet。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">&lt;servlet&gt;</div><div class="line">		&lt;servlet-name&gt;nameMyFirstServlet&lt;/servlet-name&gt;</div><div class="line">		&lt;servlet-class&gt;servlet.MyServlet&lt;/servlet-class&gt;</div><div class="line">		&lt;!-- 工程启动的时候调用此servlet，值为调用顺序 --&gt;</div><div class="line">		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;</div><div class="line">&lt;/servlet&gt;</div></pre></td></tr></table></figure>
<h2 id="Servlet构建web"><a href="#Servlet构建web" class="headerlink" title="Servlet构建web"></a>Servlet构建web</h2><hr>
<ul>
<li>原生servlet构建web的不便之处在于要配置大量的servlet，但是一般有自动生成servlet-mapping配置的插件，减少servlet的个数可以将多种业务放在一个servlet中完成，通过不同的参数区分业务。</li>
<li>用web.xml中的servlet-mapping进行路由，一个servlet可以包含多个方法，通过前台请求参数调用不同的方法。使用request.getSeesion.setAttribute()将对象或属性存到服务器中，再使用request.getSession.getAttribute()获取存放的对象。因为session是服务器全局的，所以可以全局使用。从而可以实现一个servlet可以处理多种业务的方法。</li>
</ul>
<h2 id="Cookie"><a href="#Cookie" class="headerlink" title="Cookie"></a>Cookie</h2><hr>
<p>Cookie是服务器写到浏览器的明文，默认会话级别，浏览器关闭即删除。一个浏览器最多300cookie，一个站点最多20cookie，每个最大40k。</p>
<h3 id="添加cookie"><a href="#添加cookie" class="headerlink" title="添加cookie"></a>添加cookie</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">Cookie cookie = new Cookie(“name”,val);</div><div class="line">cookie.setMaxAge(60*60);//s</div><div class="line">response.addCookie(cookie);</div></pre></td></tr></table></figure>
<h3 id="读取"><a href="#读取" class="headerlink" title="读取"></a>读取</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">response.setContentType(&quot;text/html;charset=utf-8&quot;);</div><div class="line">PrintWriter out = response.getWriter();</div><div class="line">Cookie[] cookies = request.getCookies();</div><div class="line">boolean flag = false;</div><div class="line">for (Cookie cookie : cookies) &#123;</div><div class="line">	if (cookie.getName().equals(&quot;Acookie&quot;)) &#123;</div><div class="line">		out.println(&quot;cookie found，上次登录时间是&quot; + cookie.getValue());</div><div class="line">		flag = true;</div><div class="line">		break;</div><div class="line">	&#125;</div><div class="line">&#125;</div><div class="line">if (!flag) &#123;</div><div class="line">	out.println(&quot;没有发现上次登录cookie&quot;);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h3 id="删除"><a href="#删除" class="headerlink" title="删除"></a>删除</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">cookie.setMaxAge(0)；</div><div class="line">response.addCookie(cookie);// 必须写这一句让浏览器执行cookie的销毁动作</div></pre></td></tr></table></figure>
<h3 id="cookie添加中文"><a href="#cookie添加中文" class="headerlink" title="cookie添加中文"></a>cookie添加中文</h3><ul>
<li>cookie不支持存储中文编码，需要后台进行编码，前台解码。</li>
<li>request正常存放正文，显示可以用jsp直接${userName}。cookie后台添加时使用new Cookie(“username”,URLEncoder.encode(username,”UTF-8”));，前台js使用alert(decodeURI($.cookie(‘username’))，因为decodeURI是采用UTF-8来编码的。</li>
</ul>
<h3 id="Cookie常用场景"><a href="#Cookie常用场景" class="headerlink" title="Cookie常用场景"></a>Cookie常用场景</h3><ul>
<li>常用于：上次登录时间、浏览商品记录、用户登录的用户名和密码(加密后)。<ul>
<li>上次登录时间：用户登录时，将时间作为一个cookie值添加到response，注意cookie保存时间<code>setMaxAge(60*60*24*10)//10天</code>，0是为了删除，负数是设置为会话级别(关闭浏览器则删除)，cookie默认是会话级别。</li>
<li>记住用户登录的用户名：用户登录时将用户名添加到cookie，在登录框中用户名默认值设置为读取的cookie值。</li>
<li>浏览商品记录：浏览信息写入cookie，在特定页面读取cookie，并获取信息展示到界面上。</li>
</ul>
</li>
</ul>
<h2 id="Session"><a href="#Session" class="headerlink" title="Session"></a>Session</h2><hr>
<h3 id="Session基础"><a href="#Session基础" class="headerlink" title="Session基础"></a>Session基础</h3><ul>
<li>Session属于服务器端，服务器为每个浏览器在内存中存储独有的session。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">HttpSession session = Request.getSession();//如果有该浏览器对应的session则返回session，没有则为其新建。//如果设置getSession(false)则没有时不新建，返回null</div><div class="line">session.setAttribute(“”,””);//添加属性</div><div class="line">session.remove(“”);//删除属性</div></pre></td></tr></table></figure>
<ul>
<li>注意session.setAttribute是服务器中的session的属性，request.getAttribute、request.setAttribute用于与用户进行参数交互。</li>
<li>可以存放多个属性，或者对象，重名则覆盖，默认30min，修改工程web.xml配置中servlet-config(min)，存在时间是发呆时间(间隔时间)，一旦使用就重新计时生命周期。或者session.setInterval(second)。或者修改tomcat中的servlet-config修改tomcat中的所有生命时间。</li>
<li>关闭项目，reload项目，时间到期，session.invalidate()会使session失效。</li>
<li>Session有sessionId，服务器为每个浏览器创建一个session，将其id传到JSESSIONID给浏览器的cookie，可以自己添加cookie进行使用。</li>
</ul>
<h3 id="Session常用场景"><a href="#Session常用场景" class="headerlink" title="Session常用场景"></a>Session常用场景</h3><ul>
<li>Session经常用于图片验证、购物对象列表放到session中。但是session放在服务器内存，不能过大使用，否则压力大。<ul>
<li>图片验证：产生的随机数放到session中，并将随机数生成图片给页面(注意session中的随机数覆盖，随机图片设置禁止缓存)，验证的时候先验证用户的输入是否与session中的随机数相等。</li>
<li>购物车：将购物车中的数据放到session域中。可以结合hashmap、linkedList存放物品，以进行商品分组、顺序保存。</li>
</ul>
</li>
</ul>
<h3 id="Session原理"><a href="#Session原理" class="headerlink" title="Session原理"></a>Session原理</h3><ul>
<li>因为session对应每个浏览器的原理是：将session对应的JSESSIONID作为一个cookie传递到浏览器中，session.getId()。而网站的cookie都是自动全部都随着请求发送到服务器的，所以request可以自动根据JSESSIONID进行识别。</li>
<li>实现浏览器重启后，仍访问之前的session：实现方法就是将JSESSIONID写到一个cookie中。所以重启后JSESSIONID仍然存在。request可以自动根据JSESSIONID进行识别。Session有对应的path，不同路径下的session重名不覆盖。</li>
</ul>
<h4 id="禁用cookie后获取会话的JSESSIONID"><a href="#禁用cookie后获取会话的JSESSIONID" class="headerlink" title="禁用cookie后获取会话的JSESSIONID"></a>禁用cookie后获取会话的JSESSIONID</h4><ul>
<li>Cookie是servlet之间共享session的关键，所以禁用cookie会导致问题。一种解决方法是url重写：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">request.getSession();//必须访问一下session</div><div class="line">String url = “/cart/buyBook?id=1”;</div><div class="line">url = response.encodeURL(url)；//此时url将会添加JSESSIONID，变成“/cart/buyBook;jsessionid=454671487asdf8798?id=1”</div></pre></td></tr></table></figure>
<ul>
<li>将url写到页面上，用户访问该url，后台就可以获取到JSESSIONID。</li>
</ul>
<h2 id="ServletContext"><a href="#ServletContext" class="headerlink" title="ServletContext"></a>ServletContext</h2><hr>
<h3 id="servletContext基础"><a href="#servletContext基础" class="headerlink" title="servletContext基础"></a>servletContext基础</h3><ul>
<li>servletContext在web应用启动的时候自动创建，在服务器中，可以被所有的客户端访问。当应用关闭、tomcat关闭、reload会销毁servletContext。</li>
<li>servletContext的域对象包括了整个web应用，所以对所有的客户端都是统一的。</li>
</ul>
<h3 id="servletContext使用"><a href="#servletContext使用" class="headerlink" title="servletContext使用"></a>servletContext使用</h3><ul>
<li>设置使用。ServletContext是对整个web项目的，所以不同的servlet获取到的servletContext是同一个，不同用户或者浏览器也是对应同一个servletContext。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">public class CreatServletContext extends HttpServlet &#123;</div><div class="line">	private static final long serialVersionUID = -4965652427708598938L;</div><div class="line">	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException &#123;</div><div class="line">	&#125;</div><div class="line">	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException &#123;</div><div class="line">		PrintWriter printWriter = response.getWriter();</div><div class="line">		response.setContentType(&quot;text/html;charset=utf-8&quot;);</div><div class="line"></div><div class="line">		/** 获取servletContext对象 */</div><div class="line">		ServletContext servletContext = this.getServletContext();//推荐此方法</div><div class="line">		// ServletContext servletContext2 = this.getServletConfig().getServletContext();</div><div class="line">		/** 添加对象 */</div><div class="line">		servletContext.setAttribute(&quot;users&quot;, new Date().toString());</div><div class="line">		printWriter.println(&quot;已经将访问时间记录到servletContext中&quot;);</div><div class="line">		/** 获取对象 */</div><div class="line">		String date = (String) servletContext.getAttribute(&quot;users&quot;);</div><div class="line">		printWriter.println(&quot;获取到对象：&quot; + date);</div><div class="line">		/** 删除对象 */</div><div class="line">		servletContext.removeAttribute(&quot;users&quot;);</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h3 id="ServletContext功能"><a href="#ServletContext功能" class="headerlink" title="ServletContext功能"></a>ServletContext功能</h3><p>ServletContext功能包括：数据共享、初始化参数、servlet转发、读取资源文件。</p>
<h4 id="多个servlet通过它进行数据共享"><a href="#多个servlet通过它进行数据共享" class="headerlink" title="多个servlet通过它进行数据共享"></a>多个servlet通过它进行数据共享</h4><p>因为servletContext对所有servlet是唯一的。</p>
<h4 id="获取web应用的初始化参数"><a href="#获取web应用的初始化参数" class="headerlink" title="获取web应用的初始化参数"></a>获取web应用的初始化参数</h4><ul>
<li>所有的servlet都使用的初始化参数配置为<context-param>，获取的方法如下。</context-param></li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">response.setContentType(&quot;text/html;charset=utf-8&quot;);</div><div class="line">PrintWriter printWriter = response.getWriter();</div><div class="line">String name = this.getInitParameter(&quot;name&quot;);// 本servlet的</div><div class="line">String name1 = this.getServletConfig().getInitParameter(&quot;name&quot;);// 本servlet的</div><div class="line">String name2 = this.getServletContext().getInitParameter(&quot;name&quot;);// 全局的</div><div class="line">printWriter.println(&quot;servlet的初始化参数name=&quot; + name + name1 + &quot;&lt;br/&gt;servletContext的初始化参数name=&quot; + name2 + &quot;&lt;br&gt;&quot;);</div></pre></td></tr></table></figure>
<ul>
<li>在jsp中，可以使用initParam获取servletContext参数，减少参数修改的麻烦。</li>
<li>Web.xml中设置一些参数，如下所示。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">&lt;context-param&gt;</div><div class="line">  &lt;param-name&gt;base&lt;/param-name&gt;</div><div class="line">  &lt;param-value&gt;/tcm&lt;/param-value&gt;</div><div class="line">&lt;/context-param&gt;</div><div class="line"></div><div class="line">&lt;!-- 静态文件基路径 --&gt;</div><div class="line">&lt;context-param&gt;</div><div class="line">  &lt;param-name&gt;resources&lt;/param-name&gt;</div><div class="line">  &lt;param-value&gt;http://zcy.ckcest.cn/zcystatic/tcm&lt;/param-value&gt;</div><div class="line">&lt;/context-param&gt;</div></pre></td></tr></table></figure>
<ul>
<li>在jsp中进行参数获取。base会映射为工程发布的<code>http://ip:port/tcm，resources</code>会映射成为<code>http://zcy.ckcest.cn/zcystatic/tcm</code>，在通过对不同的域名进行代理解析，就可以实现静态文件统一存储到一个服务器上，并使用擅长静态资源服务的apache作为服务器，实现服务与静态资源（css、js、图片等）分离，业务由tomcat等动态服务器提供。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot;</div><div class="line">	href=&quot;$&#123;initParam.resources&#125;/resources/commonpages/css/nav_header.css&quot;&gt;&lt;/link&gt;</div><div class="line">&lt;a title=&quot;注册&quot; href=&quot;$&#123;initParam.base&#125;/user/registerpage&quot;&gt;注册&lt;/a&gt;</div></pre></td></tr></table></figure>
<h4 id="实现servlet转发"><a href="#实现servlet转发" class="headerlink" title="实现servlet转发"></a>实现servlet转发</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">this.getServletContext().getRequestDispatcher(&quot;/url&quot;).forward(request, response);</div></pre></td></tr></table></figure>
<h4 id="读取资源文件"><a href="#读取资源文件" class="headerlink" title="读取资源文件"></a>读取资源文件</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">// 放在webapp/webRoot目录下的读取</div><div class="line">InputStream inputStream = this.getServletContext().getResourceAsStream(&quot;/res/servlet/dbRoot.properties&quot;);// 以webapp为/</div><div class="line">Properties properties = new Properties();</div><div class="line">properties.load(inputStream);</div><div class="line">String path = this.getServletContext().getRealPath(&quot;res/servlet/dbRoot.properties&quot;);// 注意如果是tomcat发布会因打包拷贝改变真实路径</div><div class="line">printWriter.print(&quot;passwd1=&quot; + properties.getProperty(&quot;passwd&quot;) + &quot;&lt;br&gt;&quot;);</div><div class="line">printWriter.println(&quot;绝对路径为：&quot; + path + &quot;&lt;br&gt;&quot;);//获取真实路径后方便文件读取</div><div class="line"></div><div class="line">// 如果文件放在src目录下，应使用类加载器读取</div><div class="line">InputStream inputStream2 = this.getClass().getResourceAsStream(&quot;/servlet/db.properties&quot;);//以classpath包含的路径为根目录</div><div class="line">//InputStream inputStream2 = this.getClass().getClassLoader().getResourceAsStream(&quot;/servlet/db.properties&quot;);//默认使用class文件的根目录</div><div class="line">Properties properties2 = new Properties();</div><div class="line">properties2.load(inputStream2);</div><div class="line">printWriter.print(&quot;passwd2=&quot; + properties2.getProperty(&quot;passwd&quot;) + &quot;&lt;br&gt;&quot;);</div></pre></td></tr></table></figure>
<h3 id="ServletContext-Demo"><a href="#ServletContext-Demo" class="headerlink" title="ServletContext Demo"></a>ServletContext Demo</h3><p>ServletContext常用于：网站在线人数计数器、显示在线用户、简单的聊天系统。一般来说就是既要共享一些数据，但是数据量不大且不希望写入数据库的事情可以用它。</p>
<ul>
<li>网站计数器<ul>
<li>将计数放入servletContext中，访问就+1。存在页面刷新就+1的问题，解决方法是用户判定：特定时间内用户唯一计数、用户无限期唯一计数等计数策略。</li>
<li>防止页面刷新导致表单重复提交的简单解决方法是：response.sendRedirect(url);因此登录后的url已经改变，刷新不是提交表单的url。</li>
</ul>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException &#123;</div><div class="line">	response.setContentType(&quot;text/html;charset=utf-8&quot;);</div><div class="line">	PrintWriter printWriter = response.getWriter();</div><div class="line">	if (this.getServletContext().getAttribute(&quot;cnt&quot;) == null) &#123;</div><div class="line">		printWriter.println(&quot;你是第1个访客&lt;br&gt;&quot;);</div><div class="line">		this.getServletContext().setAttribute(&quot;cnt&quot;, 1);</div><div class="line">	&#125; else &#123;</div><div class="line">		int cnt = (int) this.getServletContext().getAttribute(&quot;cnt&quot;);</div><div class="line">		cnt++;</div><div class="line">		this.getServletContext().setAttribute(&quot;cnt&quot;, cnt);</div><div class="line">		printWriter.print(&quot;你是第&quot; + cnt + &quot;个访客&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<ul>
<li>servletContext将内容写到文件<ul>
<li>方法是：写一个servlet设置为<load-on-startup>，在该servlet的init与destroy中分别为servletContext读取数据和保存数据，注意如果项目不是正常关闭（猫关闭、重启、项目关闭、重启），将会无法调用destroy。</load-on-startup></li>
<li>为了防止一些异常情况的退出，可以在init中启动线程，将数据定时写到文件中。</li>
<li>数据文件最好放在项目发布路径中，使用servletContext获取realPath，再进行文件操作。</li>
</ul>
</li>
</ul>
<h2 id="Filter"><a href="#Filter" class="headerlink" title="Filter"></a>Filter</h2><hr>
<h3 id="Filter基础"><a href="#Filter基础" class="headerlink" title="Filter基础"></a>Filter基础</h3><ul>
<li>过滤器类似于特殊的servlet，常用于身份验证、ip过滤、字符编码、关键字过滤以及自定义过滤。属于链式处理，通过chain.doFilter()执行后面的过滤器或者servlet，但是要特别注意过滤链的执行顺序问题。</li>
</ul>
<h3 id="用法"><a href="#用法" class="headerlink" title="用法"></a>用法</h3><ul>
<li>实现servlet中的Filter接口。主要含3个方法体：<ul>
<li>init()在项目启动的时候会将web.xml中所有的filter进行init。</li>
<li>doFilter()对请求和响应进行处理，可以用chain.doFilter(req,res)，执行完过滤链的内部，才能接着执行所在程序。</li>
<li>destroy()正常关闭项目时调用filter。</li>
</ul>
</li>
<li>Filter的链式特点表现在：越早调用的filter越最后退出。</li>
</ul>
<h3 id="Filter-Demo"><a href="#Filter-Demo" class="headerlink" title="Filter Demo"></a>Filter Demo</h3><h4 id="Web-xml"><a href="#Web-xml" class="headerlink" title="Web.xml"></a>Web.xml</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">&lt;!-- filter --&gt;</div><div class="line">&lt;!-- 编码过滤器 --&gt;</div><div class="line">&lt;filter&gt;</div><div class="line">	&lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;</div><div class="line">	&lt;filter-class&gt;servlet.filter.EncodingFilter&lt;/filter-class&gt;</div><div class="line">	&lt;init-param&gt;</div><div class="line">		&lt;param-name&gt;encoding&lt;/param-name&gt;</div><div class="line">		&lt;param-value&gt;utf-8&lt;/param-value&gt;</div><div class="line">	&lt;/init-param&gt;</div><div class="line">&lt;/filter&gt;</div><div class="line">&lt;filter-mapping&gt;</div><div class="line">	&lt;filter-name&gt;encodingFilter&lt;/filter-name&gt;</div><div class="line">	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;</div><div class="line">&lt;/filter-mapping&gt;</div><div class="line">&lt;!-- 记录请求过滤器 --&gt;</div><div class="line">&lt;filter&gt;</div><div class="line">	&lt;filter-name&gt;logFilter&lt;/filter-name&gt;</div><div class="line">	&lt;filter-class&gt;servlet.filter.LogFilter&lt;/filter-class&gt;</div><div class="line">&lt;/filter&gt;</div><div class="line">&lt;filter-mapping&gt;</div><div class="line">	&lt;filter-name&gt;logFilter&lt;/filter-name&gt;</div><div class="line">	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;</div><div class="line">&lt;/filter-mapping&gt;</div></pre></td></tr></table></figure>
<h4 id="EncodingFilter"><a href="#EncodingFilter" class="headerlink" title="EncodingFilter"></a>EncodingFilter</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div></pre></td><td class="code"><pre><div class="line">/**</div><div class="line"> * 编码过滤器</div><div class="line"> * </div><div class="line"> * @author dell</div><div class="line"> *</div><div class="line"> */</div><div class="line">public class EncodingFilter implements Filter &#123;</div><div class="line">	private String encoding;</div><div class="line">	private Map&lt;String, String&gt; params = new HashMap&lt;&gt;();</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void init(FilterConfig filterConfig) throws ServletException &#123;</div><div class="line">		// 在web.xml中被调用后读取参数等设置</div><div class="line">		System.out.println(&quot;EncodingFilter init，读取相应资源&quot;);</div><div class="line">		encoding = filterConfig.getInitParameter(&quot;encoding&quot;);</div><div class="line">		System.out.println(&quot;encoding: &quot;+encoding);</div><div class="line">		for (Enumeration&lt;?&gt; e = filterConfig.getInitParameterNames(); e.hasMoreElements();) &#123;</div><div class="line">			String name = (String) e.nextElement();</div><div class="line">			String value = filterConfig.getInitParameter(name);</div><div class="line">			params.put(name, value);</div><div class="line">		&#125;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)</div><div class="line">			throws IOException, ServletException &#123;</div><div class="line">		System.out.println(&quot;EncodingFilter doFilter before chain.doFilter&quot;);</div><div class="line">		request.setCharacterEncoding(encoding);</div><div class="line">		// 将请求进行链式处理，将根据web.xml的配置执行下一个filter。</div><div class="line">		chain.doFilter(request, response);</div><div class="line">		// 调用的filter可以再链式处理。链式处理完成后才会继续执行本程序。</div><div class="line">		System.out.println(&quot;EncodingFilter doFilter after chain.doFilter&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void destroy() &#123;</div><div class="line">		// 项目正常关闭时调用</div><div class="line">		System.out.println(&quot;EncodingFilter destroy，释放相应资源&quot;);</div><div class="line">		encoding = null;</div><div class="line">		params = null;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="LogFilter"><a href="#LogFilter" class="headerlink" title="LogFilter"></a>LogFilter</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line">public class LogFilter implements Filter&#123;</div><div class="line">	FilterConfig config;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void init(FilterConfig filterConfig) throws ServletException &#123;</div><div class="line">		// TODO Auto-generated method stub</div><div class="line">		System.out.println(&quot;LogFilter init&quot;);</div><div class="line">		this.config = filterConfig;</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)</div><div class="line">			throws IOException, ServletException &#123;</div><div class="line">		// TODO Auto-generated method stub</div><div class="line">		System.out.println(&quot;LogFilter doFilter before chain.doFilter&quot;);</div><div class="line">		ServletContext servletContext = this.config.getServletContext();</div><div class="line">		System.out.println(&quot;servlet就像特殊的servlet，也可读取servletContext，如：base为&quot;+servletContext.getInitParameter(&quot;base&quot;));</div><div class="line">		HttpServletRequest httpServletRequest = (HttpServletRequest) request;</div><div class="line">		System.out.println(&quot;拦截到用户请求url：&quot; + httpServletRequest.getServletPath());</div><div class="line">		chain.doFilter(request, response);</div><div class="line">		System.out.println(&quot;LogFilter doFilter after chain.doFilter&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void destroy() &#123;</div><div class="line">		// TODO Auto-generated method stub</div><div class="line">		System.out.println(&quot;LogFilter destroy&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h4 id="运行demo"><a href="#运行demo" class="headerlink" title="运行demo"></a>运行demo</h4><ul>
<li><p>发布项目时，所有filter被init，输出为：<br>EncodingFilter init，读取相应资源<br>encoding: utf-8<br>LogFilter init<br>MyHttpServlet中设置初始编码为：utf-8<br>2016-07-13 16:55:07.920:INFO::Started SelectChannelConnector@0.0.0.0:8080</p>
</li>
<li><p>访问配置完整的一个servlet，输出为：<br>EncodingFilter doFilter before chain.doFilter<br>LogFilter doFilter before chain.doFilter<br>servlet就像特殊的servlet，也可读取servletContext，如：base为/javaTools<br>拦截到用户请求url：/CreateSession<br>LogFilter doFilter after chain.doFilter<br>EncodingFilter doFilter after chain.doFilter</p>
</li>
<li><p>正常关闭项目（如tomcat的shutdown），输出为：<br>LogFilter destroy<br>EncodingFilter destroy，释放相应资源</p>
</li>
</ul>
<h2 id="Listener"><a href="#Listener" class="headerlink" title="Listener"></a>Listener</h2><hr>
<h3 id="Listener基础"><a href="#Listener基础" class="headerlink" title="Listener基础"></a>Listener基础</h3><ul>
<li>Listener监听器类似于filter，在web发布时加载，web关闭时销毁。listenter和filter一样，也早于load-on-start的servlet。经常用于数据库配置、日志配置等配置检验。</li>
<li>使用方法是实现ServletContextListener接口，主要含2个方法：<ul>
<li>contextInitialized(ServletContextEvent)初始化，项目发布时就会加载。</li>
<li>contextDestroyed(ServletContextEvent)销毁，正常关闭时调用。</li>
</ul>
</li>
</ul>
<h3 id="Listener-Demo"><a href="#Listener-Demo" class="headerlink" title="Listener Demo"></a>Listener Demo</h3><ul>
<li>web.xml中：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">&lt;!-- listener --&gt;</div><div class="line">&lt;listener&gt;</div><div class="line">	&lt;listener-class&gt;servlet.listener.TestDBListener&lt;/listener-class&gt;</div><div class="line">&lt;/listener&gt;</div></pre></td></tr></table></figure>
<ul>
<li>TestDBListener</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line">/**测试数据库连接等listener</div><div class="line"> * @author dell</div><div class="line"> *</div><div class="line"> */</div><div class="line">public class TestDBListener implements ServletContextListener&#123;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void contextInitialized(ServletContextEvent sce) &#123;</div><div class="line">		System.out.println(&quot;TestDBListener contextInitialized，测试数据库配置、日志记录的配置等&quot;);</div><div class="line">		String base = sce.getServletContext().getInitParameter(&quot;base&quot;);</div><div class="line">		System.out.println(&quot;listener也可以读取servletContext的值，如base：&quot;+base);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">	@Override</div><div class="line">	public void contextDestroyed(ServletContextEvent sce) &#123;</div><div class="line">		System.out.println(&quot;TestDBListener contextDestroyed，项目正常关闭，释放资源等&quot;);</div><div class="line">	&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h2 id="Servlet转发"><a href="#Servlet转发" class="headerlink" title="Servlet转发"></a>Servlet转发</h2><hr>
<h3 id="sendRedirect与forward"><a href="#sendRedirect与forward" class="headerlink" title="sendRedirect与forward"></a>sendRedirect与forward</h3><ul>
<li>response.sendRedirect()是重定向，response.forward()是转向。</li>
<li>response.sendRedirect(“可以是<code>http://...</code>”)是让浏览器重新发起一个请求，可以跨网络域，耗费网络资源不应太多，地址栏是变化的。</li>
<li>response.getRequestDispatcher(“/资源URI”).forward(request,response)是服务器将request转向，只能再同一个工程中，使用的request是一样的，不能跨域，可以无限转向，但是地址栏是不变的。</li>
</ul>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Java-web/" rel="tag">#Java web</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/01/12/Software/Revision control and collaborative development 版本控制和协同开发/GitLab/" rel="next" title="GitLab">
                <i class="fa fa-chevron-left"></i> GitLab
              </a>
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/01/12/Software/Text editors 文本编辑/常用的文本编辑器/" rel="prev" title="常用的文本编辑器">
                常用的文本编辑器 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    


  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/statics/images/avatar.png"
               alt="gatewayzy" />
          <p class="site-author-name" itemprop="name">gatewayzy</p>
          <p class="site-description motion-element" itemprop="description">blog website with hexo and github pages</p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">70</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">10</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">38</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
        </div>

        
        

        
        
          <div class="links-of-blogroll motion-element links-of-blogroll-inline">
            <div class="links-of-blogroll-title">
              <i class="fa  fa-fw fa-globe"></i>
              友情链接
            </div>
            <ul class="links-of-blogroll-list">
              
                <li class="links-of-blogroll-item">
                  <a href="https://github.com/gatewayzy" title="Github-gatewayzy" target="_blank">Github-gatewayzy</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="http://google.com/" title="Goolge" target="_blank">Goolge</a>
                </li>
              
                <li class="links-of-blogroll-item">
                  <a href="http://wiki.jikexueyuan.com/" title="Wiki-jike" target="_blank">Wiki-jike</a>
                </li>
              
            </ul>
          </div>
        

      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet简介"><span class="nav-number">1.</span> <span class="nav-text">Servlet简介</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet生命周期"><span class="nav-number">2.</span> <span class="nav-text">Servlet生命周期</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet实现"><span class="nav-number">3.</span> <span class="nav-text">Servlet实现</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#实现Servlet接口"><span class="nav-number">3.1.</span> <span class="nav-text">实现Servlet接口</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#继承GenericServlet类"><span class="nav-number">3.2.</span> <span class="nav-text">继承GenericServlet类</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#继承HttpServlet"><span class="nav-number">3.3.</span> <span class="nav-text">继承HttpServlet</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet-发布细节"><span class="nav-number">4.</span> <span class="nav-text">Servlet 发布细节</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Servlet通配符"><span class="nav-number">4.1.</span> <span class="nav-text">Servlet通配符</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Servlet匹配优先级"><span class="nav-number">4.2.</span> <span class="nav-text">Servlet匹配优先级</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Servlet同步"><span class="nav-number">4.3.</span> <span class="nav-text">Servlet同步</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#load-on-startup"><span class="nav-number">4.4.</span> <span class="nav-text">load-on-startup</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet构建web"><span class="nav-number">5.</span> <span class="nav-text">Servlet构建web</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Cookie"><span class="nav-number">6.</span> <span class="nav-text">Cookie</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#添加cookie"><span class="nav-number">6.1.</span> <span class="nav-text">添加cookie</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#读取"><span class="nav-number">6.2.</span> <span class="nav-text">读取</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#删除"><span class="nav-number">6.3.</span> <span class="nav-text">删除</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#cookie添加中文"><span class="nav-number">6.4.</span> <span class="nav-text">cookie添加中文</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Cookie常用场景"><span class="nav-number">6.5.</span> <span class="nav-text">Cookie常用场景</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Session"><span class="nav-number">7.</span> <span class="nav-text">Session</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Session基础"><span class="nav-number">7.1.</span> <span class="nav-text">Session基础</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Session常用场景"><span class="nav-number">7.2.</span> <span class="nav-text">Session常用场景</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Session原理"><span class="nav-number">7.3.</span> <span class="nav-text">Session原理</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#禁用cookie后获取会话的JSESSIONID"><span class="nav-number">7.3.1.</span> <span class="nav-text">禁用cookie后获取会话的JSESSIONID</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ServletContext"><span class="nav-number">8.</span> <span class="nav-text">ServletContext</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#servletContext基础"><span class="nav-number">8.1.</span> <span class="nav-text">servletContext基础</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#servletContext使用"><span class="nav-number">8.2.</span> <span class="nav-text">servletContext使用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ServletContext功能"><span class="nav-number">8.3.</span> <span class="nav-text">ServletContext功能</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#多个servlet通过它进行数据共享"><span class="nav-number">8.3.1.</span> <span class="nav-text">多个servlet通过它进行数据共享</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#获取web应用的初始化参数"><span class="nav-number">8.3.2.</span> <span class="nav-text">获取web应用的初始化参数</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#实现servlet转发"><span class="nav-number">8.3.3.</span> <span class="nav-text">实现servlet转发</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#读取资源文件"><span class="nav-number">8.3.4.</span> <span class="nav-text">读取资源文件</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ServletContext-Demo"><span class="nav-number">8.4.</span> <span class="nav-text">ServletContext Demo</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Filter"><span class="nav-number">9.</span> <span class="nav-text">Filter</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Filter基础"><span class="nav-number">9.1.</span> <span class="nav-text">Filter基础</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#用法"><span class="nav-number">9.2.</span> <span class="nav-text">用法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Filter-Demo"><span class="nav-number">9.3.</span> <span class="nav-text">Filter Demo</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Web-xml"><span class="nav-number">9.3.1.</span> <span class="nav-text">Web.xml</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#EncodingFilter"><span class="nav-number">9.3.2.</span> <span class="nav-text">EncodingFilter</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#LogFilter"><span class="nav-number">9.3.3.</span> <span class="nav-text">LogFilter</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#运行demo"><span class="nav-number">9.3.4.</span> <span class="nav-text">运行demo</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Listener"><span class="nav-number">10.</span> <span class="nav-text">Listener</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Listener基础"><span class="nav-number">10.1.</span> <span class="nav-text">Listener基础</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Listener-Demo"><span class="nav-number">10.2.</span> <span class="nav-text">Listener Demo</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Servlet转发"><span class="nav-number">11.</span> <span class="nav-text">Servlet转发</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#sendRedirect与forward"><span class="nav-number">11.1.</span> <span class="nav-text">sendRedirect与forward</span></a></li></ol></li></ol></div>
            
          </div>
        </section>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">gatewayzy</span>
</div>

<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Mist
  </a>
</div>

        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.0.1"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.1"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.0.1"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.1"></script>



  



  




  
  

  
  <script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
        processEscapes: true,
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
  </script>

  <script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
      var all = MathJax.Hub.getAllJax(), i;
      for (i=0; i < all.length; i += 1) {
        all[i].SourceElement().parentNode.className += ' has-jax';
      }
    });
  </script>
  <script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>



  

  
<script type="text/javascript" async src="//push.zhanzhang.baidu.com/push.js">
</script>


</body>
</html>
